// Copyright (C) 2010  Joan Puigcerver Perez, <joapuipe@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#ifndef __MAPKEY_HPP__
#define __MAPKEY_HPP__

#include <cstring>
#include <string>

/**
 * \class MapKey
 *
 * Class used as the key for people's map. Internally it stores a string (const char *), but
 * the difference is that the comparators are not case-sensitive.
 *
 * @see People
 */
class MapKey {
private:
  const char * _key;
public:
  /**
   * Construtor that creates a new MapKey object from a string (as const char *).
   * @param key Key value in the map.
   */
  MapKey(const char * key);

  /**
   * Assignation operator from an other MapKey object. Attributes are coppied.
   * @param key The other MapKey object.
   */
  MapKey& operator = (const MapKey& key);

  /**
   * Assignation operator from a string variable. Private _key variable is changed to
   * the given one.
   * @param key The new key value.
   */
  MapKey& operator = (const char * key);
  
  /**
   * Lower comparator to an other MapKey object. This performs a non case-sensitive 
   * lexicographic comparison.
   * @param key The MapKey object to compare.
   * @retval true The MapKey object on the left side is lower than the 
   *              MapKey object on the right side.
   * @retval false The MapKey object on the left side is greater or equal than the 
   *               MapKey object on the right side.
   */
  bool operator < (const MapKey& key) const;

  /**
   * Lower comparator to a string object. This performs a non case-sensitive 
   * lexicographic comparison.
   * @param key The string object to compare.
   * @retval true The MapKey object on the left side is lower than the 
   *              string object on the right side.
   * @retval false The MapKey object on the left side is greater or equal than the 
   *               string object on the right side.
   */
  bool operator < (const std::string& key) const;

  /**
   * Lower comparator to a const char pointer. This performs a non case-sensitive 
   * lexicographic comparison.
   * @param key The const char pointer to compare.
   * @retval true The MapKey object on the left side is lower than the 
   *              string pointed by the right side variable.
   * @retval false The MapKey object on the left side is greater or equal than the 
   *              string pointed by the right side variable.
   */
  bool operator < (const char * key) const;

  /**
   * Greater comparator to an other MapKey object. This performs a non case-sensitive 
   * lexicographic comparison.
   * @param key The MapKey object to compare.
   * @retval true The MapKey object on the left side is greater than the 
   *              MapKey object on the right side.
   * @retval false The MapKey object on the left side is lower or equal than the 
   *               MapKey object on the right side.
   */
  bool operator > (const MapKey& key) const;

  /**
   * Greater comparator to a string object. This performs a non case-sensitive 
   * lexicographic comparison.
   * @param key The string object to compare.
   * @retval true The MapKey object on the left side is greater than the 
   *              string object on the right side.
   * @retval false The MapKey object on the left side is lower or equal than the 
   *               string object on the right side.
   */
  bool operator > (const std::string& key) const;

  /**
   * Greater comparator to a const char pointer. This performs a non case-sensitive 
   * lexicographic comparison.
   * @param key The const char pointer to compare.
   * @retval true The MapKey object on the left side is greater than the 
   *              string pointed by the right side variable.
   * @retval false The MapKey object on the left side is lower or equal than the 
   *              string pointed by the right side variable.
   */
  bool operator > (const char * key) const;

  /**
   * Equal comparator to an other MapKey object. This performs a non case-sensitive 
   * lexicographic comparison.
   * @param key The MapKey object to compare.
   * @retval true The MapKey object on the left side is equal to the 
   *              MapKey object on the right side.
   * @retval false The MapKey object on the left side is distinct to the 
   *               MapKey object on the right side.
   */
  bool operator == (const MapKey& key) const;

  /**
   * Equal comparator to a string object. This performs a non case-sensitive 
   * lexicographic comparison.
   * @param key The string object to compare.
   * @retval true The MapKey object on the left side is equal to the 
   *              string object on the right side.
   * @retval false The MapKey object on the left side is distinct to the 
   *               string object on the right side.
   */
  bool operator == (const std::string& key) const;

  /**
   * Equal comparator to a const char pointer. This performs a non case-sensitive 
   * lexicographic comparison.
   * @param key The const char pointer to compare.
   * @retval true The MapKey object on the left side is equal to the 
   *              string pointed by the right side variable.
   * @retval false The MapKey object on the left side is distinct to the 
   *              string pointed by the right side variable.
   */
  bool operator == (const char * key) const;

  /**
   * Distinct comparator to an other MapKey object. This performs a non case-sensitive 
   * lexicographic comparison.
   * @param key The MapKey object to compare.
   * @retval true The MapKey object on the left side is distinct to the 
   *              MapKey object on the right side.
   * @retval false The MapKey object on the left side is equal to the 
   *               MapKey object on the right side.
   */
  bool operator != (const MapKey& key) const;

  /**
   * Distinct comparator to a string object. This performs a non case-sensitive 
   * lexicographic comparison.
   * @param key The string object to compare.
   * @retval true The MapKey object on the left side is distinct to the 
   *              string object on the right side.
   * @retval false The MapKey object on the left side is equal to the 
   *               string object on the right side.
   */
  bool operator != (const std::string& key) const;

  /**
   * Distinct comparator to a const char pointer. This performs a non case-sensitive 
   * lexicographic comparison.
   * @param key The const char pointer to compare.
   * @retval true The MapKey object on the left side is distinct to the 
   *              string pointed by the right side variable.
   * @retval false The MapKey object on the left side is equal to the 
   *              string pointed by the right side variable.
   */
  bool operator != (const char * key) const;
  
  /**
   * This operator returns address allocated by the MapKey object.
   * Useful to treat a MapKey object as a const char pointer.
   */
  operator const char * () const;
};

#endif
